/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.pipeparser.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Vector;

/**
 *
 * @author carlos
 */
public class ParamValuePattern {

    private Map<String, Integer> items = new HashMap<String, Integer>();

    private Vector<Vector> db = new Vector<Vector>();

    public void createARMinerFile(String pipesDir){

        createARMinerItems(pipesDir);

        addIndexToMap();

        

        Iterator it = items.keySet().iterator();
        while(it.hasNext()){
            String key = (String)it.next();
            //System.out.println(key + " : " + items.get(key));

            System.out.println(items.get(key) + " " + key);
        }

        System.out.println("BEGIN_DATA");

        Iterator itDb = db.iterator();
        int count = 0;
        while(itDb.hasNext()){
            Vector trans = (Vector)itDb.next();
            count++;

            Iterator itTrans = trans.iterator();
            while(itTrans.hasNext()){
                String item = (String)itTrans.next();
                //System.out.println("\t" + item);

                Integer idx = items.get(item);

                System.out.print(idx + " ");
                
            }

            System.out.println();


        }

        System.out.println("END_DATA");
        

        /*
        //Test Printing
        Iterator itDb = db.iterator();
        int count = 0;
        while(itDb.hasNext()){
            Vector trans = (Vector)itDb.next();
            count++;

            System.out.println("Transaction: " + count);

            Iterator itTrans = trans.iterator();
            while(itTrans.hasNext()){
                String item = (String)itTrans.next();
                System.out.println("\t" + item);
            }


        }
         */

        

    }

    public void addIndexToMap(){
        Iterator it = items.keySet().iterator();

        int idx = 0;
        while(it.hasNext()){
            String key = (String)it.next();
            idx++;
            items.put(key, idx);
        }
    }

    public void createARMinerItems(String pipesDir){
        
        try{

                File dir = new File(pipesDir);

                String[] children = dir.list();

                if(children == null){
                    System.out.println("Directory does not exists");
                    System.exit(1);
                }

                for(int i = 0; i < children.length; i++){
                    String filename = children[i];

                    String filepath = "";

                    if(filename.contains("pipe")){
                        filepath = pipesDir + filename;
                    }else{
                        continue;
                    }

                    File jsonFile = new File(filepath);
                    BufferedReader reader = new BufferedReader(new FileReader(jsonFile));

                    Pipe pipe = new Pipe(reader);

                    //Listing of modules
                    LinkedList modules = pipe.getModules();
                    Iterator moduleIt = modules.iterator();
                    
                    while(moduleIt.hasNext()){
                        Map module = (Map)moduleIt.next();
                        String type = (String)module.get("type");
                        
                        
                        if(type.contains("pipe:"))
                            continue;                     

                        if(!module.get("type").equals("fetchpage"))
                            continue;

                        //System.out.println(module.get("type"));

                        Vector<String> trans = new Vector<String>();
                        Map confParam = (Map)module.get("conf");

                        //This is mainly to treat the case of the "output" component of a Pipe
                        if(confParam == null)
                            continue;

                        Iterator itConf = confParam.keySet().iterator();

                        while(itConf.hasNext()){
                            String confName = (String)itConf.next();

                            if(confName.equals("embed"))
                                continue;

                            Object p = confParam.get(confName);

                            if(p instanceof Map){                                
                                recParamValues((Map)p, confName, trans);
                            }else if (p instanceof LinkedList){
                                //System.out.print("\t" + confName);
                                //recParamValues((LinkedList)p, "\t\t");
                            }

                        }

                        db.add(trans);

                    }

                    reader.close();

                }


                
                
        }catch(Exception e){

            e.printStackTrace();
            
        }

    }

    //Recursive method to navigate through a Map/List hierarchy
    private void recParamValues(Map map, String itemStr, Vector trans){
        Iterator it = map.keySet().iterator();

        while(it.hasNext()){
            String key = (String)it.next();
            Object obj = map.get(key);

            if(!key.equals("type"))
                itemStr = itemStr + "." + key;

            if(obj instanceof Map){
                recParamValues((Map)obj, itemStr, trans);
                return;
            }else if (obj instanceof LinkedList){
                recParamValues((LinkedList)obj, itemStr);
                return;
            }

            if(!key.equals("type")){
                //System.out.println(itemStr + "<=" + obj);
                items.put(itemStr + "<=" + obj, -1);
                trans.add(itemStr + "<=" + (String)obj);
            }

        }
    }

    //Recursive method to navigate through a List/Map hierarchy
    private void recParamValues(LinkedList list, String shift){

        for(int i = 0; i < list.size(); i++){
            Map map = (Map)list.get(i);

            Iterator it = map.keySet().iterator();

            while(it.hasNext()){
                String key = (String)it.next();

                Object obj = map.get(key);

                if(obj instanceof Map){
                    //recParamValues((Map)obj, shift + "\t");
                }else if(obj instanceof LinkedList){
                    //recParamValues((LinkedList)obj, shift + "\t");
                }                
            }

            System.out.println();
        }
    }

    public void printModuleConfig(String pipesDir){

        try{

                File dir = new File(pipesDir);

                String[] children = dir.list();

                if(children == null){
                    System.out.println("Directory does not exists");
                    System.exit(1);
                }

                for(int i = 0; i < children.length; i++){
                    String filename = children[i];

                    String filepath = "";

                    if(filename.contains("pipe")){
                        filepath = pipesDir + filename;
                    }else{
                        continue;
                    }

                    File jsonFile = new File(filepath);
                    BufferedReader reader = new BufferedReader(new FileReader(jsonFile));

                    Pipe pipe = new Pipe(reader);

                    //Listing of modules
                    LinkedList modules = pipe.getModules();
                    Iterator moduleIt = modules.iterator();

                    while(moduleIt.hasNext()){
                        Map module = (Map)moduleIt.next();
                        String type = (String)module.get("type");


                        if(type.contains("pipe:"))
                            continue;

                        //if(!module.get("type").equals("textinput"))
                        //    continue;

                        System.out.println(module.get("type"));

                        Vector<String> trans = new Vector<String>();
                        Map confParam = (Map)module.get("conf");

                        //This is mainly to treat the case of the "output" component of a Pipe
                        if(confParam == null)
                            continue;

                        Iterator itConf = confParam.keySet().iterator();

                        while(itConf.hasNext()){
                            String confName = (String)itConf.next();

                            if(confName.equals("embed"))
                                continue;

                            Object p = confParam.get(confName);

                            if(p instanceof Map){
                                recParamValues((Map)p, confName, trans);
                            }else if (p instanceof LinkedList){
                                //System.out.print("\t" + confName);
                                //recParamValues((LinkedList)p, "\t\t");
                            }

                        }

                        db.add(trans);

                    }

                    reader.close();

                }




        }catch(Exception e){

            e.printStackTrace();

        }

    }

}
